<?php

namespace FoxLib\Commands;

use Illuminate\Console\Command;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\DB;

class TableTraceCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:table-trace';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'table trace';

    protected $projectId;

    protected $token;

    protected $host;

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        try {
            $apiTraceConfigFile =  base_path() . '/apitrace.json';
            if (file_exists($apiTraceConfigFile)) {
                $apiTraceConfig = json_decode(file_get_contents($apiTraceConfigFile), true);
                $this->checkConfig('paths', $apiTraceConfig);
                $this->checkConfig('host', $apiTraceConfig);
                $this->token = $apiTraceConfig['token'];
                $this->host = $apiTraceConfig['host'];
                $database = DB::getDatabaseName();
                $tables = DB::select('show table status from ' . $database);
                $tablesSchema = [];
                foreach ($tables as $tableObj) {
                    $table = $tableObj->Name;
                    if ($table == 'migrations') {
                        continue;
                    }
                    $tablesSchema[$table] = [
                        'engine' => $tableObj->Engine,
                        'collation' => $tableObj->Collation,
                        'comment' => $tableObj->Comment,
                        'columns' => $this->parseColumns($table),
                        'indexes' => $this->parseIndexes($table)
                    ];
                }
                $this->syncTables($database, $tablesSchema);
            }
        } catch (\Exception $e) {
            var_dump($e->getMessage());
        }
    }

    private function checkConfig($key, $config)
    {
        if (empty($config[$key])) {
            var_dump($key . '不存在或为空');die;
        }
    }

    private function parseColumns($table)
    {
        $columnArr = [];
        $columns = DB::select('show full columns from ' . $table);
        foreach ($columns as $column) {
            $columnArr[]= [
                'field' => $column->Field,
                'type' => $column->Type,
                'isNull' => $column->Null,
                'default' => $column->Default,
                'comment' => $column->Comment
            ];
        }
        return $columnArr;
    }


    private function parseIndexes($table)
    {
        $indexArr = [];
        $indexes = DB::select('show keys from ' . $table);
        foreach ($indexes as $index) {
            if (empty($indexArr[$index->Key_name])) {
                $indexArr[$index->Key_name] = [
                    'columns' => $index->Column_name,
                    'unique' => !$index->Non_unique
                ];
            } else {
                $indexArr[$index->Key_name]['columns'] .=  ',' . $index->Column_name;
            }
        }
        return $indexArr;
    }



    private function syncTables($database, $tables)
    {
        $client = new Client();
        $response = $client->post($this->host . '/api/sync/tables',
            [
                'json' => [
                    'database' => $database,
                    'tables' => $tables
                ]
            ]);
        $result = json_decode($response->getBody(), true);
        if (!empty($result['error'])) {
            var_dump($result['error']);die;
        } else {
            var_dump($result['name'] . ' 接口同步成功');
        }
    }
}
